#define  _CRT_SECURE_NO_WARNINGS
#include "threadcache.h"
#include "CentralCache.h"
void* Threadcache::allocate(size_t size)
{
	assert(size < max_size);
	size_t alignsize = Sizemodify::Roundsize(size);
	size_t index = Sizemodify::Index(size);
	if (!_freelistarray[index].Empty())//该桶不为空
		return _freelistarray[index].pop();
	else//该桶为空，找下一层central cache
		return FetchFromCentralCache(index, alignsize);////////////////size
}
void* Threadcache::FetchFromCentralCache(size_t index, size_t size)
{
	size_t batchNum = min(_freelistarray[index].Maxsize(), Sizemodify::sizetonum(size));//通过size算出需要开多少个
	if (_freelistarray[index].Maxsize() == batchNum) _freelistarray[index].Maxsize()++;	//慢增长
	void* start = nullptr;
	void* end = nullptr;
	size_t actualnum = CentralCache::getcentralcache()->FetchRangobj(start, end, batchNum, size, index);
	assert(actualnum >= 1);
	if (actualnum == 1) assert(start == end);
	else _freelistarray[index].pushrange(*((void**)start), end, actualnum - 1);//返回一块,剩下的挂起来
	return start;
}

void Threadcache::ListToolong(Freelist& list, size_t size)
{
	void* start = nullptr;
	void* end = nullptr;
	list.Poprange(start, end);
	CentralCache::getcentralcache()->realse_to_central_span(start, size);
}

void Threadcache::deallocate(void* ptr, size_t size)
{
	assert(ptr);
	assert(size <= max_size);
	size_t index = Sizemodify::Index(size);//算出属于第几个桶
	_freelistarray[index].push(ptr);//头插到该桶内

	//当链表长度大于一次性申请的长度时，就开始释放链表中的内存给CentralCache
	if (_freelistarray[index].Size() >= _freelistarray[index].Maxsize()) ListToolong(_freelistarray[index], size);
}
